package systems;

import general.Case;
import general.Mechanisme;
import geometry.PointSI;
import geometry.Zone;
import graphique.C;

import java.util.ArrayList;

public class PlantSystem
{
	public ArrayList<Arbre> aa = new ArrayList<Arbre>();
	
	public ArrayList<Foret> af = new ArrayList<Foret>();

	private Case[][][]	cases;

	private int	ni;

	private int	nm;

	private int	nj;

	private Mechanisme	m;
	
	public void creationForets(Case[][][] cases)
	{
		this.cases = cases;
		
		for( int l = 0 ; l < 6 ; l++ )
		{
			for( int i = 0 ; i < cases[0].length ; i++ )
			{
				for( int j = 0 ; j < cases[0][0].length ; j++ )
				{

					float lat = (float) (Math.abs( cases[l][i][j].zone.p1.sz ) / C.rayon);
					
					if( cases[l][i][j].zone.p1.alt > C.borneBeach && cases[l][i][j].zone.p1.alt < C.borneMontain && lat < C.borneArtic )
					{
						//System.out.println( cases[l][i][j].p );
						float facteurPole = 1;
						double modAlt = 1 - Math.abs( ((C.borneMontain-C.borneBeach)/2  - (C.borneMontain - cases[l][i][j].zone.p1.alt))/((C.borneMontain-C.borneBeach)/2 ) );
						
						//System.out.println(" alt " + cases[l][i][j].p.alt + " Bo : " + bo );

						if( lat > C.borneWinter && lat < C.borneArtic )
							facteurPole = 1 -(lat-C.borneWinter)/(C.borneArtic-C.borneWinter);
						
						if( Math.random() > 1 - modAlt * C.facteurVegeAlt * facteurPole )
						{
							//System.out.println("Dis : " + distanceForet( cases[l][i][j] ) );
							if( distanceForet( cases[l][i][j] ) > 0.8 )
							{
								Foret f = new Foret( cases[l][i][j] );
								af.add(f);
								//System.out.println("Creation foret");
							}
						}
					}
				}
			}
		}
	}
	
	
	private double distanceForet(Case case1)
	{
		double min = Double.MAX_VALUE;
		
		for( int i = 0 ; i < af.size() ; i++ )
		{
			double a = distance( case1.zone.p1 , af.get(i).case1.zone.p1 );
			
			if( min > a )
			{
				min = a;
			}
		}
		return min;
	}


	private double distance(PointSI p1, PointSI p2)
	{
		return Math.sqrt( Math.pow( p1.sx - p2.sx , 2) + Math.pow( p1.sy - p2.sy , 2) + Math.pow( p1.sz - p2.sz , 2) );
	}


	public PlantSystem(Mechanisme m)
	{
		this.m = m;
	}
	/*
	public static void main(String[] args)
	{
		for( float i = 0 ; i < 1 ; i += 0.01 )
		{
			if( i > C.borneBeach && i < C.borneMontain )
			{
				double bo = Math.abs( ((C.borneMontain-C.borneBeach)/2  - (C.borneMontain - i))/((C.borneMontain-C.borneBeach)/2 ) );
				
				System.out.println(" alt " + i + " Bo : " + bo );
			}
		}
	}*/

	public void construireVege(Case[][][] cases)
	{
		for( int l = 0 ; l < 6 ; l++ )
		{
			for( int i = 0 ; i < cases[0].length ; i++ )
			{
				for( int j = 0 ; j < cases[0][0].length ; j++ )
				{

					float lat = (float) (Math.abs( cases[l][i][j].zone.p1.sz ) / C.rayon);
					
					if( cases[l][i][j].zone.p1.alt > C.borneBeach && cases[l][i][j].zone.p1.alt < C.borneMontain && lat < C.borneArtic )
					{
						//System.out.println( cases[l][i][j].p );
						float facteurPole = 1;
						double modAlt = 1 - Math.abs( ((C.borneMontain-C.borneBeach)/2  - (C.borneMontain - cases[l][i][j].zone.p1.alt))/((C.borneMontain-C.borneBeach)/2 ) );
						
						//System.out.println(" alt " + cases[l][i][j].p.alt + " Bo : " + bo );

						if( lat > C.borneWinter && lat < C.borneArtic )
							facteurPole = 1 -(lat-C.borneWinter)/(C.borneArtic-C.borneWinter);
						
						if( Math.random() > 1 - modAlt * C.facteurVegeAlt * facteurPole )
						{
							if( distanceForet( cases[l][i][j] ) < 0.1 + Math.random()/3 )
							{
								Arbre a = new Arbre( cases[l][i][j] );
								
								a.decalage( Math.random() , Math.random() );
								
								cases[l][i][j].la.add( a );
								
								aa.add(a);
							}
						}
					}
				}
			}
		}
		
		System.out.println("Arbres construits : " + aa.size() );
	}

	public void avancer( )
	{
		for( int i = 0 ; i < aa.size() ; i++ )
		{
			if( Math.random() < 0.5 )
				aa.get(i).age++;
			
			if( aa.get(i).mode == 0 )
			{
				if( aa.get(i).age >= 10 * C.nNivArbre-5 )
					aa.get(i).age = C.arbreAgeAgon;
			}
			else if( aa.get(i).mode == 1 )
			{
				if( aa.get(i).age > C.arbreAgeFeuDisp )
				{
					aa.get(i).mode = 2;
				}
				
				if( aa.get(i).age > C.arbreAgeFeuTransSol )
				{
					m.colorCases.add( aa.get(i).case1 );
				}
				
				for( int j = 0 ; j < aa.get(i).voisin.size() ; j++ )
				{
					if( Math.random() > aa.get(i).disVoi.get(j)/C.porteeFeuForet && aa.get(i).voisin.get(j).mode == 0 && aa.get(i).voisin.get(j).inter == 0 )
					{
						aa.get(i).voisin.get(j).inter = 1;
					}
					
					if( aa.get(i).voisin.get(j).inter == 1 )
					{
						aa.get(i).voisin.get(j).inter = 0;
						aa.get(i).voisin.get(j).mode = 1;
						aa.get(i).voisin.get(j).age = 0;
					}
				}
			}
		}
	}
	
	private void transformerBordure()
	{
		// 1 - 0
		if( nm == 0 && ni >= cases[0].length )
		{
			nm = 1;
			ni = cases[0].length-1-(ni-cases[0].length);
		}
		else if( nm == 1 && ni >= cases[0].length )
		{
			nm = 0;
			ni = cases[0].length-1-(ni-cases[0].length);
		}
		
		// 2 - 0
		if( nm == 0 && nj >= cases[0].length )
		{
			nm = 2;
			int temp = ni;
			ni = cases[0].length-1-(nj-cases[0].length);
			nj = temp;
		}
		else if( nm == 2 && ni >= cases[0].length )
		{
			nm = 0;
			int temp = nj;
			nj = cases[0].length-1-(ni-cases[0].length);
			ni = temp;
		}
		
		// 1 - 2
		if( nm == 0 && nj >= cases[0].length )
		{
			nm = 3;
			nj = cases[0].length-1-(nj-cases[0].length);
		}
		else if( nm == 3 && nj >= cases[0].length )
		{
			nm = 0;
			nj = cases[0].length-1-(nj-cases[0].length);
		}
		
		// 4 - 0
		if( nm == 0 && ni <= -1 )
		{
			nm = 4;
			ni = cases[0].length-1-(ni-1);
		}
		else if( nm == 4 && ni >= cases[0].length )
		{
			nm = 0;
			ni = (ni-cases[0].length);
		}
		
		// 3 - 1
		if( nm == 1 && ni <= -1 )
		{
			nm = 3;
			ni = cases[0].length-1-(ni-1);
		}
		else if( nm == 3 && ni >= cases[0].length )
		{
			nm = 1;
			ni = (ni-cases[0].length);
		}
		
		// 4 - 2
		if( nm == 2 && nj <= -1 )
		{
			nm = 4;
			nj = cases[0].length-1-(nj-1);
		}
		else if( nm == 4 && nj >= cases[0].length )
		{
			nm = 2;
			nj = (nj-cases[0].length);
		}
		
		// 5 - 1
		if( nm == 1 && nj <= -1 )
		{
			nm = 5;
			nj = cases[0].length-1-(nj-1);
		}
		else if( nm == 5 && nj >= cases[0].length )
		{
			nm = 1;
			nj = (nj-cases[0].length);
		}
		
		// 5 - 0
		if( nm == 0 && nj <= -1 )
		{
			nm = 5;
			int temp = ni;
			ni = cases[0].length-1-(nj-1);
			nj = temp;
		}
		else if( nm == 5 && ni >= cases[0].length )
		{
			nm = 0;
			int temp = nj;
			nj = (ni-cases[0].length);
			ni = temp;
		}
		
		// 5 - 4
		if( nm == 4 && nj <= -1 )
		{
			nm = 5;
			nj = -(nj+1);
		}
		else if( nm == 5 && nj <= -1 )
		{
			nm = 4;
			nj = -(nj+1);
		}
		
		// 3 - 5
		if( nm == 5 && ni <= -1 )
		{
			nm = 3;
			int temp = nj;
			nj = -(ni+1);
			ni = temp;
		}
		else if( nm == 3 && nj <= -1 )
		{
			nm = 5;
			int temp = ni;
			ni = -(nj+1);
			nj = temp;
		}
		
		// 3 - 4
		if( nm == 4 && ni <= -1 )
		{
			nm = 3;
			ni = -(ni+1);
		}
		else if( nm == 3 && ni <= -1 )
		{
			nm = 4;
			ni = -(ni+1);
		}
		
		// 3 - 2
		if( nm == 2 && ni <= -1 )
		{
			nm = 3;
			int temp = nj;
			nj = cases[0].length-1-(ni+1);
			ni = temp;
		}
		else if( nm == 3 && nj >= cases[0].length )
		{
			nm = 2;
			int temp = ni;
			ni = -(nj-cases[0].length);
			nj = temp;
		}
	}


	public void construireVoisin()
	{
		for( int i = 0 ; i < aa.size() ; i++ )
		{
			for( int j = 0 ; j < aa.size() ; j++ )
			{
				double dis = distance( aa.get(i).moy , aa.get(j).moy );
				
				if( dis < C.porteeFeuForet )
				{
					aa.get(i).voisin.add( aa.get(j) );
					aa.get(i).disVoi.add( dis );
				}
			}
		}
	}
}
